/*
 * Created on Fri Jun 08 2018 by Ronnie Ren (zhaosong.ren) from Accenture
 *
 * Copyright (c) 2018 DingXin information & technology limited company.
 */


export let GetLazyProperty = function <T>(name: string, constructorFunc: () => T) {
  let val = this["__" + name];
  if (!val) {
    val = constructorFunc();
    this["__" + name] = val;
  }
  return val;
};


export class JSONMapping {

  static PropertyKeyToJSONKeyMap() {
    return {};
  }

  static generatePropertyKeyToJSONkeyMap(obj: JSONMapping) {
    const ownProperties = Object.getOwnPropertyNames(obj);
    const overriddenMapping: { [key: string]: any } = this.PropertyKeyToJSONKeyMap();

    return ownProperties.reduce((result, prop) => {
      const newKey = overriddenMapping[prop];
      if (newKey && newKey.length > 0) {
        result[prop] = newKey;
      }
      else {
        result[prop] = prop;
      }
      return result;

    }, {} as { [key: string]: any });

  }

  static mapFromJSON(json, obj) {
    if (!json || Object.keys(json).length <= 0) {
      return;
    }
    const keyMapping = this.generatePropertyKeyToJSONkeyMap(obj);
    // this.hasMappingError = true;
    for (let key of Object.keys(keyMapping)) {
      const val = this.getValueByKeyPath(keyMapping[key], json);
      if (val !== undefined) {
        const translator = this.JSONValueTranslator(key);
        if (translator) {
          obj[key] = translator(val);
        }
        else {
          obj[key] = val;
        }
        // if (this.hasMappingError) {
        //     this.hasMappingError = false;
        // }
      }
    }
  }

  // compatiable origin attr
  static compatiableOriginAttr(keyPath: string, originJSON: { [key: string]: any }) {
    let keyPathArray = keyPath.split(",");
    let value = null;
    keyPathArray.forEach((item) => {
      let middleVariable = this.getValueByKeyPath(item, originJSON);
      if (middleVariable || middleVariable === 0) {
        value = middleVariable;
      }
    });
    return value;
  }

  static getValueByKeyPath(keyPath: string, fromJSON: { [key: string]: any }) {
    let subKeyPaths = keyPath.split("|");
    let retVal;
    for (let aKeyPath of subKeyPaths) {
      let keys = aKeyPath.split(".");
      let val = fromJSON;
      for (let key of keys) {
        if (key.length >= 0) {
          val = val[key];
          if (val === undefined) {
            break;
          }
        }
      }
      if (val !== undefined) {
        retVal = val;
        if (val !== null) {
          break;
        }
      }
    }
    return retVal;
  }


  static JSONValueTranslator(propertyKey) {
    return null;
  }

  hasMappingError: boolean;

  constructor(json) {
    this.hasMappingError = false;
  }




}

